import 'package:flutter/material.dart';
import 'page.dart';
import '../util.dart';
import 'package:flutter_pink_app/business/token.dart';

// 路由代理类, 直接混入ChangeNotifier和PopNavigatorRouterDelegateMixin
class BiliRouterDelegate extends RouterDelegate<BiliPageStatus>
    with PopNavigatorRouterDelegateMixin<BiliPageStatus>, ChangeNotifier {
  final List<BiliPageStatus> _history = [
    BiliPageStatus('/')
  ]; // 私有的历史栈，初始时只有一个根目录

  final GlobalKey<NavigatorState> _key = GlobalKey<NavigatorState>(); // 私有导航栈

  // 递归查找代理
  static BiliRouterDelegate of(BuildContext ctx) {
    final res = Router.of(ctx).routerDelegate;
    // 递归出口
    if (res == null) {
      return null;
    }
    // 找到就返回，否则就递归
    if (res is BiliRouterDelegate) {
      return res;
    }
    return of(ctx);
  }

  // 代理推入页面方法
  void push(BiliPageStatus status) {
    assert(judgetMapExistKey(generatePageMap(status), status.path),
        '当前路由表中不存在输入的路径对应的组件。');
    _history.add(status);
    notifyListeners(); // 通知重建
  }

  // 代理替换页面方法
  void replace(BiliPageStatus status) {
    assert(judgetMapExistKey(generatePageMap(status), status.path),
        '当前路由表中不存在输入的路径对应的组件。');
    _history
      ..removeLast()
      ..add(status);
    notifyListeners();
  }

  // 返回顶层页面状态
  BiliPageStatus peek() {
    return _history.last;
  }

  // 代理弹出页面方法
  bool pop() {
    if (_history.length == 1) {
      _popFalseByLength();
      return false;
    }
    _history.removeLast();
    notifyListeners();
    return true;
  }

  // 因为长度pop失败私有方法
  void _popFalseByLength() {
    logCurrStackTrace();
    print('当前栈中仅存一个页面，无法弹出，${_history[0]}');
  }

  // 全局唯一的给Navigator key
  @override
  GlobalKey<NavigatorState> get navigatorKey => _key;

  // 首页登入钩子
  @override
  Future<void> setInitialRoutePath(BiliPageStatus configuration) async {
    final tokenValue = await getToken();
    print("setInitialRoutePath, configuration:${configuration.path}");
    // 检查登陆状态
    if (tokenValue.length > 0) {
      configuration.path = '/main';
    }
    return setNewRoutePath(configuration);
  }

  // 直接设置路径
  @override
  Future<void> setNewRoutePath(BiliPageStatus configuration) {
    print('setNewRoutePath调用 :$configuration');
    if (configuration.path.isEmpty ||
        judgetMapExistKey(generatePageMap(configuration), configuration.path) ==
            false) {
      return Future.value(null);
    }
    _history
      ..clear()
      ..add(configuration); // 清空路由栈至只有一个页面
    notifyListeners(); // 提示重建
    return Future.value(null);
  }

  // 调用Navigator.pop时触发的函数
  bool _navigatorPopHook(Route<dynamic> route, dynamic res) {
    print('_navigatorPopHook调用');
    if (_history.length == 1) {
      _popFalseByLength();
      return false;
    }
    _history.removeLast();
    notifyListeners(); // 提示重建
    return route.didPop(res);
  }

  @override
  Widget build(BuildContext context) {
    return Navigator(
      key: _key,
      onPopPage: _navigatorPopHook,
      pages: [
        for (BiliPageStatus status in _history) buildCupertinoPage(status)
      ],
    );
  }
}
